﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SurvivalStrategy.Modules;

namespace SurvivalStrategy
{
    //abstrakcyjna klasa na ktorej bazuja wszystkie kontrolery
    public abstract class EntityController
    {
        private int id;
        public int ID
        {
            get { return id; }
        }
        private Dictionary<BehaviorTags, List<BahaviorModuleFunction>> functions;       //zbior wszystkich dostepnych funkcji z wszystkich dostepnym
        private RequestCommunicator requestCommunicator;                                // behavior modulow, tej listy wybierane sa najlepsze funkcje w zaleznosci od otrzymanego zadania 

        protected List<BahaviorModuleFunction> activeFunctions;                               
                                                                                        // ale to do uzgodniania w zaleznosci od dalszych pomyslow
        public EntityController()
        {
            functions = new Dictionary<BehaviorTags, List<BahaviorModuleFunction>>();
            activeFunctions = new List<BahaviorModuleFunction>();
        }

        public virtual void SendRequest(int senderID, int recieverID, ActionTags tag, ActionModuleArgs args, int priority, int lifeSpan)    //wysyla zlecenie
        {
            requestCommunicator.AddRequest(new Request(senderID, recieverID, tag, args, priority, lifeSpan));
        }
        
        public virtual void SendRequest(int senderID, int recieverID, ActionTags tag, ActionModuleArgs args)    //wysyla zlecenie
        {
            requestCommunicator.AddRequest(new Request(senderID, recieverID, tag, args));
        }

        public void SetID(int id)
        {
            this.id = id;
        }

        public void SetRequestCommunicator(RequestCommunicator requestCommunicator)
        {
            this.requestCommunicator = requestCommunicator;
        }

        public virtual void Update()
        {
            for (int i = activeFunctions.Count - 1; i >= 0; i--)        //tymczasowe, jezeli ma funckje wykonuje go tak dlugo az skonczy
            {
                if (activeFunctions[i].BehaviorModuleFunc())
                    activeFunctions.Remove(activeFunctions[i]);
            }
        }

        public BahaviorModuleFunction GetBestBehavior(BehaviorTags tag)     //szuka funkcji o podanym tagu z najwyzszym priorytetem
        {                                                                   // i ustawia ja jako aktywna
            BahaviorModuleFunction result = null;
            int resultPriority = int.MinValue;

            foreach (BahaviorModuleFunction func in functions[tag])
            {
                int priority = func.BehaviorModulePriority();
                if (resultPriority < priority)
                {
                    result = func;
                    resultPriority = priority;
                }
            }
            return result;
        }
           
        public void AddModule(BehaviorModule module)    //dodaje funkcje modulu pod odpowiednie tagi w slowniku
        {
            module.SetID(this.id);
            module.SetController(this);

            foreach (BahaviorModuleFunction func in module.ModuleFunctions)
            {
                if (functions.ContainsKey(func.Tag))
                    functions[func.Tag].Add(func);
                else
                {
                    functions.Add(func.Tag, new List<BahaviorModuleFunction>());
                    functions[func.Tag].Add(func);
                }
            }
        }

        public void RemoveModule(BehaviorModule module) //usuwa wszystkie funkcje podanego modulu ze zbioru 
        {
            foreach (BahaviorModuleFunction func in module.ModuleFunctions)
            {
                functions[func.Tag].Remove(func);
                if (functions[func.Tag].Count == 0)
                    functions.Remove(func.Tag);
            }
        }
    }

}
